﻿using MySql.Data.MySqlClient;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Top.Base.Common;
using Top.Base.DataBase;
using Top.Base.RedisKey;
using Top.Web;
using Top.Data;
using Top.PointStore.Business;
using Top.Redis;
using Top.Core;
using Top.Web.Api;

namespace Top.PointStore.LuckTurntable
{
    public static class LuckTurntableManager_Plus
    {
        /// <summary>
        /// 初始化化参与抽奖商品数据
        /// </summary>
        private static Top.Common.TopCacheUtil cacheUtil = new Top.Common.TopCacheUtil();

        private static ConcurrentDictionary<int, LuckProduct> dicLuckProducts = new ConcurrentDictionary<int, LuckProduct>();

        private static bool isInitialLuckProducts = false;

        private static object lockForInitialLuckProducts = new object();
        //自旋锁控制并发数据库操作
        private static System.Threading.SpinLock spinLock = new System.Threading.SpinLock();
        //控制当前用户并发Turn请求
        private static System.Collections.Concurrent.ConcurrentDictionary<Guid, int> IsUserBuying = new System.Collections.Concurrent.ConcurrentDictionary<Guid, int>(4 * Environment.ProcessorCount, 800);
        //用户转盘次数字典
        private static System.Collections.Concurrent.ConcurrentDictionary<int, int> dicUserTurnCount = new System.Collections.Concurrent.ConcurrentDictionary<int, int>();
        //已抽奖次数
        private static System.Collections.Concurrent.ConcurrentDictionary<Guid, int> userLuckNumberOfTimes = new System.Collections.Concurrent.ConcurrentDictionary<Guid, int>();
        //设置每日最大抽奖次数
        private static int everydayLuckCount = 10000;
        //每次抽奖扣除积分
        private static int everytimeDeductPoint = -50;
        //记录重置机会时间
        private static DateTime clearDate = DateTime.Now.Date;
        //未中奖角度
        private static double noWinAngle = 0;
        //内存中奖纪录
        private static ConcurrentDictionary<T_LuckRecordExpand, int> memoryLuckrecord = new ConcurrentDictionary<T_LuckRecordExpand,int>();
        static LuckTurntableManager_Plus()
        {
            InitialLuckProductList();
            InitialLuckRecordList();
        }

        /// <summary>
        /// 转盘转起来
        /// </summary>
        /// <param name="user">当前用户</param>
        /// <param name="isUsePoint">是否使用积分</param>
        /// <returns>返回抽奖结果信息</returns>
        public static async Task<LuckyResult> Turn(OAuthUser user, bool isUsePoint)
        {

            #region 初始化中奖商品
            var res = new LuckyResult();
            res.IsUsePoint = isUsePoint;
            res.State = 1;
            res.isWin = true;

            LuckProduct notWin = new LuckProduct()
            {
                Angle = noWinAngle,
                Chance = 0,
                Count = 0,
                Description = "谢谢参与",
                Kid = 0,
                LuckCount = 0,
                MaxCount = 0,
                Name = "谢谢参与",
                Point = 0,
                Rate = 1
            };

            #endregion

            #region 限制并发重复请求
            //限制同个用户多次请求并发处理
            if (!IsUserBuying.TryAdd(user.UserToken, 1))
            {
                res.Message = "抽奖人数过多排队中,请稍后再试!";
                res.State = -4;
                res.isWin = false;
                res.LuckProduct = notWin;
                return res;
            }
            #endregion

            try
            {

                #region 每日0点重置抽奖机会
                //if (DateTime.Now.Hour == 0&&clearDate!=DateTime.Now.Date)
                //{
                //    bool getTimeLock = false;
                //    try
                //    {                    
                //        spinLock.Enter(ref getTimeLock);
                //        if (DateTime.Now.Hour == 0&&clearDate!=DateTime.Now.Date)
                //        {
                //            userLuckNumberOfTimes.Clear();
                //            clearDate = DateTime.Now.Date;
                //        }                   
                //    }
                //    finally
                //    {
                //        if (getTimeLock) spinLock.Exit();
                //    }               
                //}
                #endregion

                #region 控制抽奖时间范围

                #region 控制每天抽奖时间 //

                //string luckyTime = Configs.AppSettings["LuckyTime"].ToString();

                //int startTime = Convert2.ToInt32(luckyTime.Split('|').FirstOrDefault(), 9);
                //int endTime = Convert2.ToInt32(luckyTime.Split('|').LastOrDefault(), 18);

                //int nowHour = DateTime.Now.Hour;
                //if (nowHour < startTime || nowHour > endTime)
                //{
                //    res.Message = "8.20号9:00开始抽奖,敬请期待";
                //    res.State = -1;
                //    res.isWin = false;
                //    res.LuckProduct = notWin;
                //    return res;
                //}

                #endregion


                #region 七夕活动需开启  //

                //DateTime nowDate = DateTime.Now;
                //DateTime startDate = Convert2.ToDateTime("2015-8-20 10:00");
                //DateTime endDate = Convert2.ToDateTime("2015-8-21 00:00");

                //if (nowDate < startDate)
                //{
                //    res.Message = "8.20号10:00开始抽奖,敬请期待";
                //    res.State = -1;
                //    res.isWin = false;
                //    res.LuckProduct = notWin;
                //    return res;
                //}

                //if (nowDate >= endDate)
                //{
                //    res.Message = "本次活动已结束，敬请期待下次";
                //    res.State = -1;
                //    res.isWin = false;
                //    res.LuckProduct = notWin;
                //    return res;
                //}

                #endregion


                #region 中秋活动时间 //

                //DateTime nowDate = DateTime.Now;
                //DateTime startDate = Convert3.To<DateTime>("2015-9-27 10:11");
                //DateTime endDate = Convert3.To<DateTime>("2015-9-28 00:00");

                //if (nowDate < startDate)
                //{
                //    res.Message = "9.27号10:11开始抽奖,敬请期待";
                //    res.State = -1;
                //    res.isWin = false;
                //    res.LuckProduct = notWin;
                //    return res;
                //}

                //if (nowDate >= endDate)
                //{
                //    res.Message = "本次活动已结束，敬请期待下次";
                //    res.State = -1;
                //    res.isWin = false;
                //    res.LuckProduct = notWin;
                //    return res;
                //}

                #endregion

                #region 双11活动时间
                //DateTime nowDate = DateTime.Now;
                //DateTime startDate = Convert3.To<DateTime>("2015-11-11 11:11");
                //DateTime endDate = Convert3.To<DateTime>("2015-11-12 00:00");

                //if (nowDate < startDate)
                //{
                //    res.Message = "11月11号11:11开始抽奖,敬请期待";
                //    res.State = -1;
                //    res.isWin = false;
                //    res.LuckProduct = notWin;
                //    return res;
                //}

                //if (nowDate >= endDate)
                //{
                //    res.Message = "本次活动已结束，敬请期待下次";
                //    res.State = -1;
                //    res.isWin = false;
                //    res.LuckProduct = notWin;
                //    return res;
                //} 
                #endregion

                #endregion

                #region 判断积分是否充足
                T_PointMain_new brokerPoint = await LuckProductManager.GetBrokerPoint(user);
                //判断剩余积分是否具有购买能力
                if (brokerPoint.F_PointBalance < -everytimeDeductPoint)
                {
                    res.Message = "积分不足";
                    res.State = -2;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }
                #endregion

                #region 抽奖次数控制
                //已参加过抽奖
                int lucknumbercount = userLuckNumberOfTimes.GetOrAdd(user.UserToken, 0);

                if (lucknumbercount >= everydayLuckCount)
                {
                    res.Message = "您的抽奖机会已用完!";
                    res.State = -1;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }
                int newlucknumbercount = lucknumbercount + 1;
                userLuckNumberOfTimes.TryUpdate(user.UserToken, newlucknumbercount, lucknumbercount);
                #endregion

                #region 获取抽奖商品列表、本次抽奖消耗积分

                var luckProducts = GetLuckProductList();

                int usePoint = everytimeDeductPoint; //扣除积分

                #endregion

                //TODO 每个经纪人只能参与一次，从中奖纪录来判断，如果已经参与过，提示您已参与
                //TODO 不判断分销公司
                //TODO 每个奖品设置当天最大中奖数量
                //TODO ！！如果当天或者所有的奖品都已经对换，则提示今日商品已兑完，请明天再来



                #region 520活动//

                //var exchangeNotDisplay = new[]
                //{
                //    "谢谢参与",
                //    "200积分",
                //    "500积分"
                //};

                //var luckRecordNotDisplay = new[]
                //{
                //    "谢谢参与"
                //};


                //var winList = new[]
                //{
                //    "200积分",
                //    "500积分",
                //    "10元话费",
                //    "20元话费",
                //    "30元话费",
                //    "50元话费",
                //    "100元话费"
                //};

                //var autoList = new[]
                //{
                //    "200积分",
                //    "500积分"
                //};

                //var productTipList = new[]
                //{
                //    "10元话费",
                //    "20元话费",
                //    "30元话费",
                //    "50元话费",
                //    "100元话费"
                //};

                #endregion

                #region 端午节//

                //var exchangeNotDisplay = new[]
                //{
                //    "谢谢参与",
                //    "100积分",
                //    "200积分",
                //    "500积分"
                //};

                //var luckRecordNotDisplay = new[]
                //{
                //    "谢谢参与",
                //    "再来一次"
                //};


                //var winList = new[]
                //{
                //    "100积分",
                //    "200积分",
                //    "500积分",
                //    "超市卡50元",
                //    "粽子礼盒",
                //    "坚果礼盒"
                //};

                //var autoList = new[]
                //{
                //    "100积分",
                //    "200积分",
                //    "500积分"
                //};

                //var productTipList = new[]
                //{
                //    "超市卡50元",
                //    "粽子礼盒",
                //    "坚果礼盒"
                //};

                #endregion

                #region 七夕节//

                //var exchangeNotDisplay = new[]
                //{
                //    "3000积分",
                //    "2000积分",
                //    "1000积分",
                //    "500积分"
                //};

                //var luckRecordNotDisplay = new[]
                //{
                //    "谢谢参与",
                //    "再来一次"
                //};


                //var winList = new[]
                //{
                //    "3000积分",
                //    "2000积分",
                //    "1000积分",
                //    "500积分",
                //    "仿陶瓷情侣杯",
                //    "德芙巧克力",
                //    "杜蕾斯一盒",
                //    "销冠手机"
                //};

                //var autoList = new[]
                //{
                //    "3000积分",
                //    "2000积分",
                //    "1000积分",
                //    "500积分"
                //};

                //var productTipList = new[]
                //{
                //    "仿陶瓷情侣杯",
                //    "德芙巧克力",
                //    "杜蕾斯一盒",
                //    "销冠手机"
                //};

                #endregion

                #region 中秋节 //

                //var exchangeNotDisplay = new[]
                //{
                //    "1000积分",
                //    "500积分"
                //};

                //var luckRecordNotDisplay = new[]
                //{
                //    "谢谢参与",
                //    "再来一次"
                //};

                //var winList = new[]
                //{
                //    "1000积分",
                //    "500积分",
                //    "4G无线键盘鼠标套装",
                //    "海盗狗竹炭包",
                //    "打火机",
                //    "数据线"
                //};

                //var autoList = new[]
                //{
                //    "1000积分",
                //    "500积分"
                //};

                //var productTipList = new[]
                //{
                //    "4G无线键盘鼠标套装",
                //    "海盗狗竹炭包",
                //    "打火机",
                //    "数据线"
                //};

                #endregion

                #region 中秋节

                //Dictionary<string, string> dicExchangeNotDisplay = new Dictionary<string, string>();
                //dicExchangeNotDisplay.Add("1000积分", string.Empty);
                //dicExchangeNotDisplay.Add("500积分", string.Empty);

                //Dictionary<string, string> dicLuckRecordNotDisplay = new Dictionary<string, string>();
                //dicLuckRecordNotDisplay.Add("谢谢参与", string.Empty);
                //dicLuckRecordNotDisplay.Add("再来一次", string.Empty);

                //Dictionary<string, string> dicWinList = new Dictionary<string, string>();
                //dicWinList.Add("1000积分", string.Empty);
                //dicWinList.Add("500积分", string.Empty);
                //dicWinList.Add("4G无线键盘鼠标套装", string.Empty);
                //dicWinList.Add("海盗狗竹炭包", string.Empty);
                //dicWinList.Add("打火机", string.Empty);
                //dicWinList.Add("数据线", string.Empty);

                //Dictionary<string, string> dicAutoList = new Dictionary<string, string>();
                //dicAutoList.Add("1000积分", string.Empty);
                //dicAutoList.Add("500积分", string.Empty);


                //Dictionary<string, string> dicProductTipList = new Dictionary<string, string>();
                //dicProductTipList.Add("4G无线键盘鼠标套装", string.Empty);
                //dicProductTipList.Add("海盗狗竹炭包", string.Empty);
                //dicProductTipList.Add("打火机", string.Empty);
                //dicProductTipList.Add("数据线", string.Empty);

                #endregion

                Dictionary<string, string> dicLuckRecordNotDisplay = new Dictionary<string, string>();
                dicLuckRecordNotDisplay.Add("谢谢参与", string.Empty);

                Dictionary<string, string> dicWinList = new Dictionary<string, string>();
                dicWinList.Add("销冠手机", string.Empty);
                dicWinList.Add("蓝牙耳机", string.Empty);
                dicWinList.Add("电暖气", string.Empty);
                dicWinList.Add("打火机", string.Empty);
                dicWinList.Add("1000积分", string.Empty);
                dicWinList.Add("2000积分", string.Empty);
                dicWinList.Add("3000积分", string.Empty);

                #region （可以考虑用于防止宕机内存数据丢失）判断当天抽奖机会是否用完

                //gc-f   1、result > 0 统计正常 2、result < 0 redis出现异常
                var joinCount = await JoinCount(user.UserToken.ToString());
                if (joinCount < 0)
                {
                    res.Message = "抽奖人数过多,请稍后再试!";
                    res.State = -4;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }
                if (joinCount >= everydayLuckCount)
                {
                    res.Message = "您的抽奖机会已用完!";
                    res.State = -1;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }
                //int luckRecordNumByBrokerKid = await GetLuckRecord(user.UserToken.ToString(), 249);
                //if (luckRecordNumByBrokerKid > 0)
                //{
                //    joinCount--;
                //    //兑现一个再来一次
                //    int upres = await UpdateLuckRecordCashedCheck(user.UserToken.ToString(), 249);
                //    if (upres < 0)
                //    {
                //        res.Message = "抽奖人数过多,请稍后再试!";
                //        res.State = -4;
                //        res.isWin = false;
                //        res.LuckProduct = notWin;
                //        return res;
                //    }
                //}
                //else
                //{
                //    //int lotteryNum = Convert2.ToInt32(Top.Web.Configs.AppSettings["LotteryNum"].ToString(), 2);
                //    int lotteryNum = 2;
                //    if (joinCount >= lotteryNum)
                //    {
                //        res.Message = "您的抽奖机会已用完!";
                //        res.State = -1;
                //        res.isWin = false;
                //        res.LuckProduct = notWin;
                //        return res;
                //    }
                //}
                #endregion

                #region 处理业务

                //全奖品数量
                var totalCountAll = 0;
                //剩余奖品数量
                var totalCount = 0;

                foreach (var item in dicLuckProducts)
                {
                    totalCountAll += item.Value.Count;
                    totalCount += (item.Value.MaxCount - item.Value.LuckCount);
                }

                //foreach (var luckProduct in luckProducts)
                //{
                //    //if (luckProduct.Name == "再来一次") continue;
                //    totalCountAll += luckProduct.Count;
                //    totalCount += (luckProduct.MaxCount - luckProduct.LuckCount);
                //}

                if (totalCountAll <= 0 || totalCount <= 0)
                {
                    //res.Message = "今天的奖品兑完啦,明天再来吧！";
                    //res.Message = "手慢啦，该奖品已抽完啦！";
                    res.Message = "本次活动奖品已抽完，敬请期待下次.";
                    res.State = -1;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }

                //if (string.IsNullOrWhiteSpace(user.UserToken.ToString()))
                //{
                //    res.Message = "经纪人不存在！";
                //    res.State = -1;
                //    res.isWin = false;
                //    res.LuckProduct = notWin;
                //    return res;
                //}

                if (luckProducts.Count == 0)//奖品不存在
                {
                    res.Message = "活动太活火爆，奖品已经没啦";
                    res.State = -3;
                    res.isWin = false;
                    res.LuckProduct = notWin;
                    return res;
                }

                res.LuckProduct = GetRand();//计算概率 返回是否中奖信息 

                if (res.LuckProduct == null)
                {
                    res.Message = "出问题啦,再试一次吧";
                    res.State = -4;
                    res.isWin = false;
                    res.LuckProduct = notWin;

                    newlucknumbercount = lucknumbercount - 1;
                    userLuckNumberOfTimes.TryUpdate(user.UserToken, newlucknumbercount, lucknumbercount);
                    return res;
                }

                if (res.LuckProduct.LuckCount >= res.LuckProduct.MaxCount)
                {
                    res.LuckProduct.Description = "该礼品已抽完，未扣积分，再来一次.";
                    res.LuckProduct = res.LuckProduct;//感谢参与
                    res.Message = "该礼品已抽完，未扣积分，再来一次.";
                    res.State = 2;
                    notWin.Description = "该礼品已抽完，未扣积分，再来一次.";
                    res.isWin = false;

                    newlucknumbercount = lucknumbercount - 1;
                    userLuckNumberOfTimes.TryUpdate(user.UserToken, newlucknumbercount, lucknumbercount);
                    return res;
                }

                //扣除积分
                if (res.IsUsePoint)//判断本次是否使用积分
                {
                    usePoint = 0;
                    res.IsUsePoint = false;
                }

                //if (res.LuckProduct.Name == "再来一次")//如果是再来一次,下次抽奖将不使用积分
                //{
                //    res.IsUsePoint = true;
                //    newlucknumbercount = lucknumbercount - 1;
                //    userLuckNumberOfTimes.TryUpdate(user.UserToken, newlucknumbercount, lucknumbercount);
                //}


                //判断中奖商品是否有库存 gc
                if (res.LuckProduct.Count <= 0)
                {
                    res.Message = "该礼品已抽完，未扣积分，再来一次.";
                    res.State = 2;
                    notWin.Description = "该礼品已抽完，未扣积分，再来一次.";
                    res.isWin = true;
                    res.LuckProduct = notWin;//感谢参与
                    newlucknumbercount = lucknumbercount - 1;
                    userLuckNumberOfTimes.TryUpdate(user.UserToken, newlucknumbercount, lucknumbercount);
                    //===参与活动记录一次机会,不扣减库存及积分，注销此行代码===
                    return res;
                }

                #endregion

                #region


                var exchangeKid = 0;

                //构造数据
                T_LuckRecordExpand luckRecord = new T_LuckRecordExpand();
                luckRecord.UserToken = user.UserToken.ToString();
                luckRecord.ExchangeKid = exchangeKid;
                luckRecord.LuckProductKid = res.LuckProduct.Kid;
                luckRecord.OrderNo = DateTime.Now.ToString("yyyyMMddHHmmfff");
                luckRecord.UserName = user.Name ?? user.NickName;
                luckRecord.PhoneNumber = user.Phone;
                luckRecord.F_CompanyName = "";// user.F_BrokerCompanyName;
                luckRecord.F_IsDisplay = dicLuckRecordNotDisplay.ContainsKey(res.LuckProduct.Name) ? 0 : 1;
                luckRecord.IsWin = dicWinList.ContainsKey(res.LuckProduct.Name) ? 1 : 0;
                luckRecord.CreateTime = DateTime.Now;
                luckRecord.F_ProductName = res.LuckProduct.Name;
                luckRecord.BrokerKid = user.BrokerID;


                #region 扣除积分 更新库存

                //抽中奖品，扣积分
                if (res.LuckProduct.Count > 0)
                {
                    //幸运大转盘抽奖消耗 gc*
                    int resultID = LuckProductManager.UpdateBrokerPoint(brokerPoint, user, usePoint, "broker.pointluck.cash");
                    if (resultID <= 0)
                    {
                        res.Message = "谢谢参与";//感谢参与
                        res.isWin = false;
                        notWin.Description = "谢谢参与";
                        res.LuckProduct = notWin;
                        return res;
                    }
                }
                //更新奖品数量    1、result > 0 统计正常   2、result <= 0 redis出现异常 lock*--内部有spinlock
                int updateCount = UpdateCount(res.LuckProduct.Kid);
                if (updateCount <= 0)
                {
                    res.Message = "谢谢参与";//感谢参与
                    res.isWin = false;
                    notWin.Description = "手慢啦，该奖品已抽完啦！";
                    res.LuckProduct = notWin;
                    LuckProductManager.UpdateBrokerPoint(brokerPoint, user, -usePoint, "broker.pointluck.refund");//退回积分
                    return res;
                }

                #endregion

                #region 插入中奖纪录 redis
                exchangeKid = await AddLuckyRecord(luckRecord, user);//返回中奖纪录ID
                if (exchangeKid <= 0)
                {
                    int temp = 0;
                    memoryLuckrecord.TryRemove(luckRecord,out temp);
                    res.Message = "谢谢参与";
                    res.State = -8;
                    res.isWin = false;
                    res.LuckProduct = notWin;//感谢参与       
                    LuckProductManager.UpdateBrokerPoint(brokerPoint, user, -usePoint, "broker.pointluck.refund");//退回积分
                    return res;
                }

                //发布订阅机制
                //抽中“谢谢参与”或“再来一次”，不执行订阅机制 
                if (dicWinList.ContainsKey(res.LuckProduct.Name) && res.LuckProduct.Count > 0)
                {
                    try
                    {
                        long resultPubID = await RedisHelper.Publish("TopsHandleLuckRecordWindowsService", string.Format("{0}#{1}", exchangeKid.ToString(), user.UserToken));
                        if (resultPubID <= 0)
                        {
                            int temp = 0;
                            memoryLuckrecord.TryRemove(luckRecord, out temp);
                            ErrorLog.WriteLog(string.Format("中奖编号：{0},物品名称：{1}，提示信息：发布失败", exchangeKid.ToString(), res.LuckProduct.Name));
                            res.Message = "谢谢参与";//感谢参与
                            res.isWin = false;
                            notWin.Description = "活动已结束";
                            res.LuckProduct = notWin;
                            return res;
                        }
                    }
                    catch (Exception)
                    {
                        int temp = 0;
                        memoryLuckrecord.TryRemove(luckRecord, out temp);
                        res.Message = "谢谢参与";//感谢参与
                        res.isWin = false;
                        notWin.Description = "活动已结束！";
                        res.LuckProduct = notWin;
                        return res;
                    }
                }

                #endregion

                return res;

                #endregion

            }
            catch (Exception ex)
            {                
                res.Message = "抽奖人数过多，请稍候再试!";
                res.State = -9;
                res.isWin = false;
                res.LuckProduct = notWin;//感谢参与
                ErrorLog.WriteLog(ex);
                return res;
            }
            finally
            {
                int value = 0;
                if (!IsUserBuying.TryRemove(user.UserToken, out value))
                {
                    IsUserBuying.TryRemove(user.UserToken, out value);
                }
            }
        }

        /// <summary>
        /// 初始化抽奖商品
        /// </summary>
        /// <returns></returns>
        public static ConcurrentDictionary<int, LuckProduct> InitialLuckProductList()
        {
            string conStr = Configs.ConnectionStrings["default"].ToString();
            try
            {
                const string sql = @"select * from T_LuckProduct";

                DataTable dt = new DataTable();//SQLHelper.ExecuteTable(sql);

                using (MySqlDataAdapter msda = new MySqlDataAdapter(sql, conStr))
                {
                    msda.Fill(dt);
                }

                if (dt.Rows.Count <= 0)
                {
                    return dicLuckProducts;
                }

                if (!isInitialLuckProducts && !dicLuckProducts.Any())
                {
                    lock (lockForInitialLuckProducts)
                    {
                        if (!isInitialLuckProducts && !dicLuckProducts.Any())
                        {
                            #region 遍历组装list集合

                            foreach (DataRow row in dt.Rows)
                            {
                                LuckProduct model = new LuckProduct();
                                if (row["ID"] != null && row["ID"].ToString() != "")
                                {
                                    model.ID = int.Parse(row["ID"].ToString());
                                }
                                if (row["Angle"] != null && row["Angle"].ToString() != "")
                                {
                                    model.Angle = int.Parse(row["Angle"].ToString());
                                }
                                if (row["Name"] != null)
                                {
                                    model.Name = row["Name"].ToString();
                                    if (model.Name == "谢谢参与")
                                    {
                                        noWinAngle = model.Angle;
                                    }
                                }
                                if (row["Chance"] != null && row["Chance"].ToString() != "")
                                {
                                    model.Chance = int.Parse(row["Chance"].ToString());
                                }
                                if (row["Count"] != null && row["Count"].ToString() != "")
                                {
                                    model.Count = int.Parse(row["Count"].ToString());
                                }
                                if (row["Point"] != null && row["Point"].ToString() != "")
                                {
                                    model.Point = int.Parse(row["Point"].ToString());
                                }
                                if (row["Description"] != null)
                                {
                                    model.Description = row["Description"].ToString();
                                }
                                if (row["Kid"] != null && row["Kid"].ToString() != "")
                                {
                                    model.Kid = int.Parse(row["Kid"].ToString());
                                }
                                if (row["Rate"] != null && row["Rate"].ToString() != "")
                                {
                                    model.Rate = int.Parse(row["Rate"].ToString());
                                }
                                if (row["MaxCount"] != null && row["MaxCount"].ToString() != "")
                                {
                                    model.MaxCount = int.Parse(row["MaxCount"].ToString());
                                }
                                if (row["LuckCount"] != null && row["LuckCount"].ToString() != "")
                                {
                                    model.LuckCount = int.Parse(row["LuckCount"].ToString());
                                }
                                dicLuckProducts.TryAdd(model.Kid, model);
                            }

                            #endregion
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[GetLuckProductList] 异常信息：{0}", ex.ToString()));
            }

            return dicLuckProducts;
        }

        public static ConcurrentDictionary<T_LuckRecordExpand,int> InitialLuckRecordList()
        {
            if (memoryLuckrecord.Count==0)
            {
                List<T_LuckRecordExpand> list = GetLuckRecordList(Pager.Create(1, 10000)).Result.ToList<T_LuckRecordExpand>();
                for (int i = 0; i < list.Count; i++)
                {
                    memoryLuckrecord.TryAdd(list[i], 1);
                }
            }            
            return memoryLuckrecord;
        }
        /// <summary>
        /// 获取抽奖商品列表
        /// </summary>
        /// <returns></returns>
        public static ConcurrentDictionary<int, LuckProduct> GetLuckProductList()
        {
            if (dicLuckProducts.Any())
            {
                return dicLuckProducts;
            }
            return InitialLuckProductList();
        }

        /// <summary>
        /// 更新抽奖奖品库存
        /// </summary>
        /// <param name="kid"></param>
        /// <returns>
        /// 1、result > 0 统计正常
        /// 2、result <= 0 redis出现异常
        /// </returns>
        public static int UpdateCount(int kid)
        {
            try
            {
                if (dicLuckProducts.ContainsKey(kid))
                {
                    LuckProduct luckProduct = dicLuckProducts[kid];
                    if (luckProduct != null)
                    {
                        bool getLock = false;

                        try
                        {
                            spinLock.Enter(ref getLock);
                            if (luckProduct.Count > 0)
                            {
                                luckProduct.Count = luckProduct.Count - 1;
                                luckProduct.LuckCount = luckProduct.LuckCount + 1;
                            }
                        }
                        finally
                        {
                            if (getLock) spinLock.Exit();
                        }

                        return 1;
                    }
                }
                return -1;
            }
            catch (Exception ex)
            {
                //Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
                Trace.TraceError(string.Format("cache操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
                return -1;
            }

            #region cache

            //try
            //{
            //    IList<LuckProduct> luckProductList = LuckTurntableManager.GetLuckProductList();
            //    foreach (var item in luckProductList)
            //    {
            //        if (item.Kid == kid && item.Count > 0 && item.LuckCount < item.MaxCount)
            //        {
            //            item.Count = item.Count - 1;
            //            item.LuckCount = item.LuckCount + 1;
            //            break;
            //        }
            //    }

            //    cacheUtil.AddObject(ProductKey.LuckProductList, luckProductList);
            //    return 1;
            //}
            //catch (Exception ex)
            //{
            //    //Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
            //    Trace.TraceError(string.Format("cache操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
            //    return -1;
            //}

            #endregion

            #region redis

            //int resultID = 0;
            //try
            //{
            //    IList<LuckProduct> luckProductList = await GetLuckProductList();
            //    foreach (var item in luckProductList)
            //    {
            //        if (item.Kid == kid && item.Count > 0 && item.LuckCount < item.MaxCount)
            //        {
            //            item.Count = item.Count - 1;
            //            item.LuckCount = item.LuckCount + 1;
            //            break;
            //        }
            //    }

            //    if (await RedisProvider.StringSet(ProductKey.LuckProductList, Json.ToJsonString(luckProductList)))
            //    {
            //        resultID = 1;
            //    }
            //    else
            //    {
            //        resultID = 0;
            //    }

            //}
            //catch (Exception ex)
            //{
            //    Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[UpdateCount] 异常信息：{0}", ex.ToString()));
            //    resultID = -1;
            //}
            //return resultID;

            #endregion

            #region sql

            //            const string sql = @"UPDATE [T_LuckProduct]
            //                                SET [Count] = [Count] - 1
            //            	                    ,[LuckCount] = [LuckCount] + 1
            //                                WHERE Kid ={0}
            //            	                    AND [Count] > 0
            //            	                    AND [LuckCount] < [MaxCount]";

            //            using (var db = new DbTour())
            //            {
            //                return await db.Sql(sql, kid).ExecuteNonQuery();
            //            }

            #endregion

        }

        /// <summary>
        /// 获取某个用户中奖次数
        /// </summary>
        /// <param name="brokerId"></param>
        /// <param name="luckProductName"></param>
        /// <returns>
        /// 1、result > 0 统计正常
        /// 2、result < 0 redis出现异常
        /// </returns>
        public static async Task<int> JoinCount(string userToken)
        {

            #region redis

            //            //try
            //            //{
            //            //    List<string> luckRecordListStr = await RedisProvider.ListRange(string.Format(ProductKey.LuckRecordListByUserKid, brokerId), 0, -1);
            //            //    return luckRecordListStr.Count();
            //            //}
            //            //catch (Exception ex)
            //            //{
            //            //    Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[JoinCount] 异常信息：{0}", ex.ToString()));
            //            //    return -1;
            //            //}

            #endregion

            #region sql
            //            string sql = string.Empty;
            //            switch (brokerId % 4)
            //            {
            //                case 0:
            //                    sql = @"SELECT Count(1) iCount
            //                                        FROM T_LuckRecord
            //                                        where UserToken={0}
            //                                        and CreateTime > {1}
            //                                        and CreateTime < {2}";
            //                    break;
            //                case 1:
            //                    sql = @"SELECT Count(1) iCount
            //                                        FROM T_LuckRecord2
            //                                        where UserToken={0}
            //                                        and CreateTime > {1}
            //                                        and CreateTime < {2}";
            //                    break;
            //                case 2:
            //                    sql = @"SELECT Count(1) iCount
            //                                        FROM T_LuckRecord3
            //                                        where UserToken={0}
            //                                        and CreateTime > {1}
            //                                        and CreateTime < {2}";
            //                    break;
            //                case 3:
            //                    sql = @"SELECT Count(1) iCount
            //                                        FROM T_LuckRecord4
            //                                        where UserToken={0}
            //                                        and CreateTime > {1}
            //                                        and CreateTime < {2}";
            //                    break;
            //            }

            #endregion

            const string sql = @"SELECT Count(1) iCount
                                                    FROM V_LuckRecord
                                                    where F_UserToken={0}
                                                    and CreateTime > {1}
                                                    and CreateTime < {2}";

            using (var db = new DbTour())
            {
                return (await db.Sql(sql, userToken, DateTime.Now.Date, DateTime.Now.Date.AddDays(1)).ExecuteScalar<int>(0));
            }

        }

        public static async Task<bool> Update(List<LuckProduct> list)
        {
            #region redis

            try
            {
                dicLuckProducts.Clear();
                foreach (var item in list)
                {
                    dicLuckProducts.TryAdd(item.ID, new LuckProduct()
                    {
                        ID = item.ID,
                        Angle = item.Angle,
                        Name = item.Name,
                        Chance = item.Chance,
                        Count = item.Count,
                        Point = item.Point,
                        Description = item.Description,
                        MaxCount = item.MaxCount,
                        LuckCount = item.LuckCount,
                        Rate = item.Rate,
                        Kid = item.ProductKid,
                        ProductKid = item.ProductKid                        
                    });
                    await LuckProductManager.Update(item);
                }

                return true;

                //return await RedisProvider.StringSet(ProductKey.LuckProductList, Json.ToJsonString(list));
            }
            catch (Exception ex)
            {
                //Trace.TraceError(string.Format("Redis操作 类名[LuckProductManager] 方法名[Update] 异常信息：{0}", ex.ToString()));
                Trace.TraceError(string.Format("cache操作 类名[LuckProductManager] 方法名[Update] 异常信息：{0}", ex.ToString()));
                return false;
            }

            #endregion
        }

        public static async Task<bool> IsJoin(int brokerId, int count = 1)
        {
            //TODO 指定周期内
            const string sql = @"SELECT Count(1)
                            FROM V_LuckRecord
                            where BrokerKid={0}
                            and CreateTime > {1}
                            and CreateTime < {2}";
            using (var db = new DbTour())
            {
                return (await db.Sql(sql, brokerId, DateTime.Now.Date, DateTime.Now.Date.AddDays(1)).ExecuteScalar<int>(0)) >= count;
            }
        }

        public static async Task<bool> IsFirst(int luckProductKid)
        {
            const string sql = @"SELECT Count(1)
                            FROM V_LuckRecord
                            where LuckProductKid={0}
                            and CreateTime > {1}
                            and CreateTime < {2}";

            using (var db = new DbTour())
            {
                return (await db.Sql(sql, luckProductKid, DateTime.Now.Date, DateTime.Now.Date.AddDays(1)).ExecuteScalar<int>(0)) <= 0;
            }
        }

        public static LuckProduct GetRand()
        {
            var temp = 0;
            var tempList = new List<Range>();

            LuckProduct outLuckProduct = null;
            foreach (var luckProduct in dicLuckProducts)
            {
                if (luckProduct.Value.LuckCount == luckProduct.Value.MaxCount && luckProduct.Value.Count <= 0)
                {
                    dicLuckProducts.TryRemove(luckProduct.Key, out outLuckProduct);
                    continue;
                }

                if (luckProduct.Value.Chance > 0)
                {
                    var range = new Range();
                    range.LuckProduct = luckProduct.Value;
                    range.minValue = temp;
                    temp += Convert.ToInt32(luckProduct.Value.Chance);
                    range.maxValue = temp;
                    tempList.Add(range);
                }
            }

            var random = new Random().Next(temp);
            LuckProduct res = null;
            foreach (var range in tempList)
            {
                if (random >= range.minValue && random < range.maxValue)
                    res = range.LuckProduct;
            }
            return res;
        }

        public static async Task<string> GetBrokerName(int brokerKid)
        {
            const string sql = @"select 
              ifnull(b.F_Title,b.F_WX_Nickname) as userName 
              from T_Broker as b 
              where b.Kid={0}";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, brokerKid).ExecuteScalar("");
            }
        }

        public static async Task<string> GetBrokerPhone(int brokerKid)
        {
            const string sql = @" select 
              b.F_Phone as Phone 
              from T_Broker as b 
              where b.Kid={0}";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, brokerKid).ExecuteScalar("");
            }
        }

        public static async Task<string> GetCompanyName(int brokerKid)
        {
            const string sql = @" select 
              b.F_BrokerCompanyName
              from T_Broker as b 
              where b.Kid={0}";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, brokerKid).ExecuteScalar("");
            }
        }


        /// <summary>
        /// 新增中奖纪录
        /// </summary>
        /// <param name="model"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        public static async Task<int> AddLuckyRecord(T_LuckRecordExpand model, OAuthUser user)
        {

            #region redis

            //try
            //{
            //    await RedisProvider.ListLPush(string.Format(ProductKey.LuckRecordListByUserKid, userKid), Json.ToJsonString(model));
            //    await RedisProvider.ListLPush(ProductKey.LuckRecordList, Json.ToJsonString(model));
            //    return 1;
            //}
            //catch (Exception ex)
            //{
            //    Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[AddLuckyRecord] 异常信息：{0}", ex.ToString()));
            //    return 0;
            //}

            #endregion

            bool getRecordLock = false;
            try
            {
                spinLock.Enter(ref getRecordLock);
                memoryLuckrecord.TryAdd(model,1);
            }
            finally
            {
                if (getRecordLock) spinLock.Exit();
            }

            //string sql = GetLuckRecordSql(userKid);
            string tokenStr = user.UserToken.ToString();
            char markchar = Convert.ToChar(tokenStr.Substring(tokenStr.Length - 2, 1));
            int mark = (int)markchar;
            string tableName = string.Empty;
            switch (mark % 4)
            {
                case 0:
                    tableName = "T_LuckRecord";
                    break;
                case 1:
                    tableName = "T_LuckRecord2";
                    break;
                case 2:
                    tableName = "T_LuckRecord3";
                    break;
                case 3:
                    tableName = "T_LuckRecord4";
                    break;
                default:
                    tableName = "T_LuckRecord";
                    break;
            }

            string sql = @"INSERT INTO " + tableName + @"
            		                    (UserName
            		                    ,PhoneNumber
            		                    ,OrderNo
            		                    ,BrokerKid
            		                    ,ExchangeKid
            		                    ,LuckProductKid
            		                    ,F_IsDisplay
            		                    ,F_CompanyName
            		                    ,CreateTime
            		                    ,IsWin
                                        ,F_UserToken)
            	                    VALUES
            		                    ({0:UserName}
            		                    ,{0:PhoneNumber}
            		                    ,{0:OrderNo}
            		                    ,{0:BrokerKid}
            		                    ,{0:ExchangeKid}
            		                    ,{0:LuckProductKid}
            		                    ,{0:F_IsDisplay}
            		                    ,{0:F_CompanyName}
            		                    ,{0:CreateTime}
            		                    ,{0:IsWin}
                                        ,{0:UserToken});
                            select LAST_INSERT_ID();";
            try
            {
                using (var db = new DbTour())
                {
                    return await db.Sql(sql, model).ExecuteScalar<int>(0);
                }
            }
            catch (Exception ex)
            {

                throw;
            }


        }

        public static async Task<IList<T_LuckRecordExpand>> GetLuckRecordList(Pager pager)
        {

            #region redis

            //List<T_LuckRecordExpand> luckProductList = new List<T_LuckRecordExpand>();
            //List<string> luckRecordListStr = await RedisProvider.ListRange(ProductKey.LuckRecordList, 0, 8);
            //if (luckRecordListStr.Count() <= 0)
            //{
            //    return luckProductList;
            //}
            //foreach (var item in luckRecordListStr)
            //{
            //    luckProductList.Add(Json.ToObject<T_LuckRecordExpand>(item));
            //}
            //DateTime startDate = DateTime.Now.Date;
            //DateTime endDate = startDate.AddDays(1);
            //return luckProductList.Where(c => c.F_IsDisplay == 1 && c.CreateTime >= startDate && c.CreateTime < endDate).ToList<T_LuckRecordExpand>();

            #endregion

            #region sql

            using (var db = new DbTour())
            {

                DateTime startDate = DateTime.Now.Date;
                DateTime endDate = startDate.AddDays(1);
                string sql = @"SELECT 
                                        l.LuckProductKid,
                                        l.UserName,
                                        l.PhoneNumber,
                                        l.CreateTime,
                                        l.F_CompanyName,
                                        ll.F_ProductName
                                        FROM V_LuckRecord AS l
                	                        left join T_PointProduct as ll on l.LuckProductKid=ll.Kid
                                        WHERE 1=1  and l.F_IsDisplay = 1 and l.CreateTime >={0} and l.CreateTime<{1}
                ";//l.F_CompanyName<>''
                try
                {
                    return await db.Sql(sql, startDate, endDate).ToList<T_LuckRecordExpand>(pager.StartNumber, pager.EndNumber, "l.CreateTime desc");

                }
                catch (Exception ex)
                {
                    
                    throw;
                }

            }

            #endregion

        }

        public static List<T_LuckRecordExpand> GetLuckRecordList()
        {
            List<T_LuckRecordExpand> list = memoryLuckrecord.Keys.ToList();
            List<T_LuckRecordExpand> list2 = list.OrderByDescending(a => a.CreateTime).Take(20).ToList();
            return list2;
        }

        public static int GetLuckRecordCount()
        {
            int recoredCount = memoryLuckrecord.Keys.Count;
            return recoredCount;
        } 

        public static async Task<int> GetLuckCount()
        {
            #region redis

            //try
            //{
            //    List<string> luckRecordListStr = await RedisProvider.ListRange(ProductKey.LuckRecordList, 0, -1);
            //    return luckRecordListStr.Count();
            //}
            //catch (Exception ex)
            //{
            //    Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[GetLuckCount] 异常信息：{0}", ex.ToString()));
            //    return 0;
            //}

            #endregion

            #region sql

            using (var db = new DbTour())
            {
                const string sql = @"select count(1) from V_LuckRecord where F_IsDisplay=1 and CreateTime > {0} and CreateTime < {1}";
                return await db.Sql(sql, DateTime.Now.Date, DateTime.Now.Date.AddDays(1)).ExecuteScalar<int>();
            }

            #endregion
        }

        public static async Task<IList<LuckRecord>> GetLuckRecordListByBrokerKid(string userToken, Pager pager)
        {
            if (string.IsNullOrWhiteSpace(userToken)) return new List<LuckRecord>();
            const string sql = @"select top 50 *
                      from V_LuckRecord as l where F_UserToken={0}";

            using (var db = new DbTour())
            {
                return await db.Sql(sql, userToken).ToList<LuckRecord>(pager.StartNumber, pager.EndNumber, "l.Createtime desc");
            }
        }

        public static async Task<bool> CheckLuckyRecord(string brokerUserToken, string OutTransactionNumber, int amount)
        {
            if (!OutTransactionNumber.Contains(','))
            {
                return false;
            }
            string[] temp = OutTransactionNumber.Split(new string[] { "|" }, StringSplitOptions.RemoveEmptyEntries);
            if (string.IsNullOrWhiteSpace(brokerUserToken)) return false;
            const string sql = @"
                select a.Kid as LuckyId,IFNULL(b.Point,0) AS Money from V_LuckRecord a left join t_luckproduct b on a.LuckProductKid = b.Kid
                where 1=1
                and a.F_UserToken = {0}
                and a.CreateTime>'2016-1-1'
                limit 1
                ";                    
            using (var db = DataBaseContext.GetDataBase("reader"))
            {
                var luckmodel = await db.Sql(sql, brokerUserToken).FirstOrDefault<LuckInfo>();
                if (luckmodel!=null)
                {
                    if (luckmodel.LuckyId ==Convert.ToInt32(temp[1])&&luckmodel.Money==amount)
                    {
                        return true;
                    }
                }
                return false;
            }
        }



        /// <summary>获取中奖记录列表
        /// </summary>
        /// <param name="phone"></param>
        /// <param name="brokerName"></param>
        /// <param name="sdt"></param>
        /// <param name="edt"></param>
        /// <param name="pager"></param>
        /// <returns></returns>
        public static async Task<IList<LuckRecord>> GetLuckList(int cityKid, int authCityKid, string phone, string brokerName, string sdt, string edt, int isSend, int isWin, string productName, Pager pager)
        {
            phone = phone.Trim();
            brokerName = brokerName.Trim();
            try
            {
                using (var db = new DbTour())
                {
                    var query = db.Table(@"SELECT a.*
        ,c.F_Address
        ,d.F_ProductName as NAME
        ,e.F_IsStatus as IsSend
    FROM V_LuckRecord a
    LEFT JOIN T_Broker b ON a.BrokerKid = b.Kid
    LEFT JOIN T_BrokerCompany c ON b.F_BrokerCompanyKid = c.Kid 
    LEFT JOIN T_PointProduct d ON a.LuckProductKid = d.Kid
    LEFT join T_ProductsExchange_new as e on e.Kid=a.ExchangeKid");


                    if (authCityKid != 0)
                    {
                        query.And(" b.F_CityKid = {0}", authCityKid);
                    }
                    else
                    {
                        if (cityKid > 0)
                        {
                            query.And(" b.F_CityKid = {0}", cityKid);
                        }
                    }

                    //List<int> frameworkKisList = await SystemManager.GetFrameworkKids(adminKid,db);
                    //if (frameworkKisList.Contains(1))
                    //{

                    //}
                    //else
                    //{
                    //    IList<AdminCityExpand> cityList = await SystemManager.GetCityListByAdminKid(adminKid);
                    //    List<int> kids = (from c in cityList select c.F_CityKid).ToList<int>();
                    //    if (kids.Any())
                    //    {
                    //        //string kidList = string.Join(",", kids);
                    //        query.And(" b.F_CityKid in ({0})", kids);
                    //    }
                    //}

                    //if (cityKid > 0)
                    //{
                    //    query.And(" b.F_CityKid = {0}", cityKid);
                    //}
                    if (isSend == 10)
                    {
                        query.And("e.F_IsStatus = {0}", (int)ExchangeState.Send);
                    }
                    else if (isSend == 9)
                    {
                        query.And("e.F_IsStatus in ({0})", new[] { "1", "3", "9" });
                    }

                    if (isWin >= 0)
                    {
                        if (isWin == 0)
                        {
                            query.And("IsWin is null");
                        }
                        else if (isWin == 1)
                        {
                            query.And("IsWin = {0}", isWin);
                        }
                    }
                    if (!string.IsNullOrEmpty(phone))
                    {
                        query.And("PhoneNumber like '%" + phone + "%'");
                    }
                    if (!string.IsNullOrWhiteSpace(brokerName))
                    {
                        query.And("UserName like '%" + brokerName + "%'");
                    }
                    if (!string.IsNullOrWhiteSpace(sdt))
                    {
                        query.And("CreateTime >= {0}", sdt);
                    }
                    if (!string.IsNullOrWhiteSpace(edt))
                    {
                        edt = Convert.ToDateTime(edt).AddDays(1).ToString();
                        query.And("CreateTime < {0}", edt);
                    }

                    if (!string.IsNullOrWhiteSpace(productName))
                    {
                        query.And("d.F_ProductName like '%" + productName + "%'");
                    }

                    return await query.ToList<LuckRecord>(pager.StartNumber, pager.EndNumber, "a.CreateTime desc");
                }
            }
            catch
            {
                return new List<LuckRecord>();
            }
        }

        /// <summary>
        /// 更新奖品发放状态
        /// </summary>
        /// <param name="id"></param>
        /// <param name="isSend"></param>
        /// <returns></returns>
        public static async Task<bool> UpdateSendStatus(int id, int isSend)
        {
            if (isSend == (int)ExchangeState.NotSend || isSend == (int)ExchangeState.Send)
            {
                using (var db = new DbTour())
                {
                    const string sql = "update T_ProductsExchange_new set F_IsStatus = {0} where Kid in (select ExchangeKid from V_LuckRecord where Kid={1})";
                    return await db.Sql(sql, isSend, id).ExecuteNonQuery() > 0;
                }
            }
            else
            {
                return false;
            }
        }



        public static async Task<LuckRecord> GetByExchangeKid(int exchangeKid)
        {
            const string sql = @"select 
l.*,e.F_ExchangeDescription,p.F_ProductName as Name
from V_LuckRecord as l
left join T_ProductsExchange_new as e on l.ExchangeKid=e.Kid
left join T_PointProduct as p on l.LuckProductKid=p.Kid
where e.Kid={0}";
            using (var db = new DbTour())
            {
                return await db.Sql(sql, exchangeKid).FirstOrDefault<LuckRecordExpan>();
            }
        }



        public static async Task<IList<T_ProductsExchangeExpand>> GetLuckRecordListByBrokerKid(Pager pager, int userKid)
        {
            using (var db = new DbTour())
            {

                DateTime startDate = DateTime.Now.Date;
                DateTime endDate = startDate.AddDays(1);
                string sql = @"SELECT  l.OrderNo,
        l.CreateTime as F_ExchangeTime,
        ll.F_ProductName,
        ll.F_PicUrl,
        100 as F_PointNum
        FROM V_LuckRecord AS l
       inner join T_PointProduct as ll on l.LuckProductKid=ll.Kid
        WHERE l.F_IsDisplay = 1 and l.CreateTime >={0} and l.CreateTime<{1} and l.BrokerKid = {2} ";
                return await db.Sql(sql, startDate, endDate, userKid).ToList<T_ProductsExchangeExpand>(pager.StartNumber, pager.EndNumber, "l.CreateTime desc");
            }

        }


        #region 中奖列表导出

        //        public static async Task<string> Export(string startTime, string endTime)
        //        {
        //            using (var db = new DbTour())
        //            {
        //                var query = db.Table(@"select
        //ISNULL(b.F_Title,b.F_WX_Nickname) as BrokerName,
        //b.F_Phone As BrokerPhone,
        //e.F_Name as CityName,
        //c.F_Title as BrokerCompanyName,
        //d.Name as AwardAmount
        //from T_LuckRecord a
        //left join T_Broker b on a.BrokerKid=b.Kid
        //left join T_BrokerCompany  c on b.F_BrokerCompanyKid=c.Kid
        //left join T_LuckProduct d on a.LuckProductKid=d.Kid 
        //left join T_ProvinceCityArea e on b.F_CityKid = e.Kid");

        //                if (!string.IsNullOrWhiteSpace(startTime))
        //                {
        //                    query.And("a.CreateTime >= {0}", startTime);
        //                }
        //                if (!string.IsNullOrWhiteSpace(endTime))
        //                {
        //                    endTime = Convert.ToDateTime(endTime).AddDays(1).ToString();
        //                    query.And("a.CreateTime < {0}", endTime);
        //                }

        //                IList<ExportLuckTurntable> resultList = await query.ToList<ExportLuckTurntable>();

        //                DataTable QueryResult = TopDataTableHelper.ToDataTable(resultList, LuckTurntableForExportFields());//获取要导出的列
        //                DataTable Export = TopDataTableHelper.CreateTable(LuckTurntableForExportTitle());//创建标头 
        //                foreach (DataRow dr in QueryResult.Rows)//导入数据
        //                {
        //                    Export.Rows.Add(dr["BrokerName"], dr["BrokerPhone"], dr["CityName"], dr["BrokerCompanyName"], dr["AwardAmount"]);
        //                }

        //                return CsvUtil.TableToScv(Export);
        //            }

        //        }


        public static async Task<string> Export(int cityKid, int adminKid, string phone, string brokerName, string startTime, string endTime, int isSend, int isWin, string productName)
        {
            using (var db = new DbTour())
            {
                var query = db.Table(@"SELECT
IfNULL(b.F_Title,b.F_WX_Nickname) as BrokerName,
b.F_Phone As BrokerPhone,
e.F_Name as CityName,
c.F_Title as BrokerCompanyName,
d.F_ProductName as AwardAmount
FROM V_LuckRecord a
LEFT JOIN T_Broker b ON a.BrokerKid = b.Kid
LEFT JOIN T_BrokerCompany c ON b.F_BrokerCompanyKid = c.Kid 
LEFT JOIN T_PointProduct d ON a.LuckProductKid = d.Kid
left join T_ProvinceCityArea e on b.F_CityKid = e.Kid
left join T_ProductsExchange_new f on a.ExchangeKid = f.Kid");

                query.And("b.F_Phone <>''");

                List<int> frameworkKisList = await SystemManager.GetFrameworkKids(adminKid);
                if (frameworkKisList.Contains(1))
                {

                }
                else
                {
                    IList<AdminCityExpand> cityList = await SystemManager.GetCityListByAdminKid(adminKid);
                    List<int> kids = (from c in cityList select c.F_CityKid).ToList<int>();
                    if (kids.Any())
                    {
                        //string kidList = string.Join(",", kids);
                        query.And(" b.F_CityKid in ({0})", kids);
                    }
                }

                if (cityKid > 0)
                {
                    query.And(" b.F_CityKid = {0}", cityKid);
                }

                if (isSend == 10)
                {
                    query.And("f.F_IsStatus = {0}", (int)ExchangeState.Send);
                }
                else if (isSend == 9)
                {
                    query.And("f.F_IsStatus in ({0})", new[] { "1", "3", "9" });
                }

                if (isWin >= 0)
                {
                    if (isWin == 0)
                    {
                        query.And("a.IsWin is null");
                    }
                    else if (isWin == 1)
                    {
                        query.And("a.IsWin = {0}", isWin);
                    }
                }

                if (!string.IsNullOrEmpty(phone))
                {
                    query.And("b.F_Phone like '%" + phone + "%'");
                }
                if (!string.IsNullOrWhiteSpace(brokerName))
                {
                    query.And("b.F_Title like '%" + brokerName + "%'");
                }

                if (!string.IsNullOrWhiteSpace(startTime))
                {
                    query.And("a.CreateTime >= {0}", startTime);
                }

                if (!string.IsNullOrWhiteSpace(endTime))
                {
                    endTime = Convert.ToDateTime(endTime).AddDays(1).ToString();
                    query.And("a.CreateTime < {0}", endTime);
                }

                if (!string.IsNullOrWhiteSpace(productName))
                {
                    query.And("d.F_ProductName like '%" + productName + "%'");
                }

                var result = await query.ExecuteDataTable();
                string path = string.Empty;
                DataTableExcel(result, string.Format("中奖名单（{0}）.xls", DateTime.Now.ToString("yyyy-MM-dd")), out path);
                //DataTable1Excel(result, GetMapPath("/Document/Template.xls"));
                return path;
            }

        }
        /// <summary>
        /// 导出Excel文件，并自定义文件名
        /// </summary>
        public static void DataTableExcel(DataTable dtData, String FileName, out string path)
        {
            string sitePath = "/Document/";
            string FilePathName = ProductsExchangeManager.GetMapPath(sitePath);
            DirectoryInfo info = Directory.CreateDirectory(FilePathName);
            FilePathName = FilePathName + FileName;
            //System.IO.File.Delete(FilePathName + FileName);
            FileStream Fs = new FileStream(FilePathName, FileMode.Create);
            StreamWriter BWriter = new StreamWriter(Fs, Encoding.UTF8);
            //将DataGrid的信息写入Excel文件 
            BWriter.Write(GetDataTableHtml(dtData));
            BWriter.Close();
            Fs.Close();
            path = sitePath + FileName;
        }

        public static string GetDataTableHtml(DataTable grid)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append("<table cellspacing=\"0\" rules=\"all\" border=\"1\" style=\"border-collapse:collapse;\">");
            sb.Append("<tr><td>经纪人姓名</td><td>联系电话</td><td>所属城市</td><td>所属公司</td><td>中奖金额</td></tr>");
            if (grid.Rows.Count > 0)
            {
                foreach (DataRow row in grid.Rows)
                {
                    sb.Append(@"<tr><td>" + (string.IsNullOrWhiteSpace(row["BrokerName"].ToString()) ? "" : row["BrokerName"]) +
                         "</td><td>" + (string.IsNullOrWhiteSpace(row["BrokerPhone"].ToString()) ? "" : row["BrokerPhone"]) +
                         "</td><td>" + (string.IsNullOrWhiteSpace(row["CityName"].ToString()) ? "" : row["CityName"]) +
                         "</td><td>" + (string.IsNullOrWhiteSpace(row["BrokerCompanyName"].ToString()) ? "" : row["BrokerCompanyName"]) +
                         "</td><td>" + (string.IsNullOrWhiteSpace(row["AwardAmount"].ToString()) ? "" : row["AwardAmount"]) +
                         "</td></tr>");
                }
            }
            else
            {
                sb.Append(@"<tr><td colspan='5' style='text-align:center'>未能找到相关信息</td></tr>");
            }
            sb.Append("</table>");

            return sb.ToString();
        }

        //public static void DataTable1Excel(DataTable dt, string path)
        //{
        //    if (dt.Rows.Count > 0)
        //    {
        //        Workbook workbook = new Workbook(); //工作簿 
        //        Worksheet sheet = workbook.Worksheets[0]; //工作表 
        //        Cells cells = sheet.Cells;//单元格 
        //        int Colnum = dt.Columns.Count;//表格列数 
        //        int Rownum = dt.Rows.Count;//表格行数 

        //        //生成行1 列名行 
        //        for (int i = 0; i < Colnum; i++)
        //        {
        //            //cells[0, i].PutValue(dt.Columns[i].ColumnName);
        //            cells[0, i].PutValue(LuckTurntableForExportTitle()[i]);
        //            cells.SetRowHeight(0, 25);
        //        }

        //        //生成数据行 
        //        for (int i = 0; i < Rownum; i++)
        //        {
        //            for (int k = 0; k < Colnum; k++)
        //            {
        //                cells[1 + i, k].PutValue(dt.Rows[i][k].ToString());
        //            }
        //            cells.SetRowHeight(1 + i, 24);
        //        }

        //        workbook.Save(path);
        //    }
        //}

        /// <summary>中奖列表表头
        /// </summary>
        /// <returns></returns>
        private static List<string> LuckTurntableForExportTitle()
        {

            return new List<string>()
            {
                "经纪人姓名",
                "类型电话",
                "所属城市",
                "所属公司",
                "中奖金额"
            };
        }

        public class ExportLuckTurntable
        {
            public string BrokerName { get; set; }
            public string BrokerPhone { get; set; }
            public string CityName { get; set; }
            public string BrokerCompanyName { get; set; }
            public string AwardAmount { get; set; }
        }

        #endregion


        public static async Task<bool> AddLog(Exception exMsg)
        {
            #region redis

            try
            {
                return await RedisProvider.ListLPush(LogKey.LogList, Json.ToJsonString(exMsg)) > 0;
            }
            catch (Exception ex)
            {
                Trace.TraceError(string.Format("Redis操作 类名[LuckTurntableManager] 方法名[AddLog] 异常信息：{0}", ex.ToString()));
                return false;
            }

            #endregion
        }


        public static async Task<IList<LuckProduct>> GetLuckProductList2()
        {
            using (var db = DataBase.Reader())
            {
                const string sql = @"select * from T_LuckProduct";
                return await db.Sql(sql).ToList<LuckProduct>();
            }
        }

    }

    public class LuckInfo
    {
        public int LuckyId { get; set; }

        public double Money { get; set; }
    }
}

